<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>WebGL Demo</title>
	
	<!--Include -->
	<script type="text/javascript" src="toji-gl-matrix-4cbb933\gl-matrix.js"></script>
	<script type="text/javascript" src="ShaderProgram.js"></script>
	
	<!--Shader definition-->	
	<script id="shader-fs" type="x-shader/x-fragment">  
		#ifdef GL_ES
		precision highp float;
		#endif
		
		//varying lowp vec4 vColor;
		vec3 eye = vec3(0,0,1);
		vec3 dir = vec3(0,1,1);
		
		varying vec3 worldPos;

		float maxDist = 2.0;
		float minStepb = 0.001;
		int maxNbStep = 32;
		float eps = 0.000001;
		
		//RayMarching Sphere calc
		float sphereDist(vec3 pos, vec3 center, float radius)
		{
			return length(center - pos) - radius;
		}		
		
		void main()
		{
			float d;
			vec4 c = vec4(0, 0, 0, 1);
			vec3 dn = normalize(eye);
			vec3 dt = dn;
			float stepped = 0.0;
			float cc;

			for (int steps = 0; steps < 32; steps++ )
			{
			   //March 1 step
			   dt = worldPos + dn * stepped;
			   d = sphereDist(dt, vec3(0.0, 0.0, -1.0), 1.0);
			   if ( d < eps )
			   {
				  gl_FragColor = vec4(0.0,0.0,1.0,1.0);
				  return;
				}
			}

			gl_FragColor = vec4(d,d,d,1.0);  // Pas de hit...
		}
	</script>  
	
	
	<script id="shader-vs" type="x-shader/x-vertex">  
		#ifdef GL_ES
		precision highp float;
		#endif
		
		uniform mat4 uPMatrix;
		uniform mat4 uMVMatrix;
		
		attribute vec3 aVertexPosition;

		varying vec3 worldPos;
		varying vec3 eye, dir;
		
		 void main(void) 
		 {  
			worldPos = (uPMatrix * vec4(aVertexPosition, 1.0)).xyz;
			gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);  
		} 
	
		/*void main(void)
		{
			vec3 e = vec3(0,0,1);
			vec3 p = vec3(0,0,1);
			
			pos = p;
			eye = e;
			//calculate world space eye ray			
			eye = (ModelViewMatrixInverse * vec4(0,0,0,1)).xyz;
			//dir = pos - eye;
			
			//calculate homogenous coordinates for interpolation
			gl_Position = modelViewProjectionMatrix * vec4(pos, 1.0);
		}*/
		
	</script> 
	
	<script type="text/javascript">
		"use strict";
		
		//Global variable
		var canvas = null
		var gl = null
		var shaderProgram = null
		var mvMatrix;
		var vertexPositionAttribute;
		var vertexColorAttribute;
		var squareVerticesBuffer;
		var squareVerticesColorBuffer;
		var perspectiveMatrix;
		
		var spawnParticuleEpsilon = 0.5;
		var vertexArray = [];
		
		
		function resize()
		{
			canvas.width = window.innerWidth
			canvas.height = window.innerHeight
			gl.viewport(0, 0, canvas.width, canvas.height)
		}
		
		function init()
		{
			document.body.innerHTML = ""
			
			document.body.style.margin = 0
			
			canvas = document.createElement("canvas")
			document.body.appendChild(canvas)
			document.body.style.overflow = "hidden"
			canvas.border = 0
			canvas.style.padding = 0
			canvas.style.margin = 0
			
			gl = canvas.getContext("experimental-webgl")
			resize()
			
			window.onresize = resize
			start();	
			render(0)
		}
		
		function render(time)
		{
			drawScene();
			requestAnimFrame(render)
		}
		/**
		 * Provides requestAnimationFrame in a cross browser way.
		 * This function has been directly taken from https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/demos/common/webgl-utils.js
		 */
		var requestAnimFrame = (function() {
		  return window.webkitRequestAnimationFrame ||
				 window.mozRequestAnimationFrame
		})();
				
	
		function start() 
		{     
			// Only continue if WebGL is available and working  
    
			if (gl) 
			{  
				gl.clearColor(0.0, 0.0, 0.0, 1.0);                      // Set clear color to black, fully opaque  
				gl.enable(gl.DEPTH_TEST);                               // Enable depth testing  
				gl.depthFunc(gl.LEQUAL);                                // Near things obscure far things  
				gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);      // Clear the color as well as the depth buffer.  
				
				initShaders();
				initBuffers();
			}  
		}  
		
		function initShaders() 
		{
			var fragmentShader = getShader(gl, "shader-fs");
			var vertexShader = getShader(gl, "shader-vs");
		  
			// Create the shader program
		  
			shaderProgram = new ShaderProgram(vertexShader, fragmentShader);
			shaderProgram.bind();
		  
			vertexPositionAttribute = shaderProgram.getAttributeLocation("aVertexPosition");
			gl.enableVertexAttribArray(vertexPositionAttribute);
		  
			/*vertexColorAttribute = shaderProgram.getAttributeLocation("aVertexColor");  
			gl.enableVertexAttribArray(vertexColorAttribute);  */
		}
	
		function getShader(gl, id) 
		{  
			var shaderScript, theSource, currentChild, shader;  
			  
			shaderScript = document.getElementById(id);  
			  
			if (!shaderScript) 
			{  
				return null;  
			}  
			  
			theSource = "";  
			currentChild = shaderScript.firstChild;  
			  
			while(currentChild) 
			{  
				if (currentChild.nodeType == currentChild.TEXT_NODE) 
				{  
					theSource += currentChild.textContent;  
				}  
				  
				currentChild = currentChild.nextSibling;  
			}  
			
			return theSource
		}  
  
		function initBuffers() 
		{  
			squareVerticesBuffer = gl.createBuffer();  
			gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer);  
			
			  var vertices = 
			  [  
				canvas.width,  canvas.height,  0.0,  
				-canvas.width, canvas.height,  0.0,  
				canvas.width,  -canvas.height, 0.0,  
				-canvas.width, -canvas.height, 0.0  
			  ];  
				
			  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);  
			  
			/*var colors = 
			[  
				1.0,  1.0,  1.0,  1.0,    // white  
				1.0,  0.0,  0.0,  1.0,    // red  
				0.0,  1.0,  0.0,  1.0,    // green  
				0.0,  0.0,  1.0,  1.0     // blue  
			];  
				
			 squareVerticesColorBuffer = gl.createBuffer();  
			 gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesColorBuffer);  
			 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);*/
		} 
		
		
		function drawScene() 
		{  
			gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);  

			perspectiveMatrix = mat4.perspective(45, canvas.width / canvas.height, 0.1, 1000.0);  

			mvMatrix = mat4.identity();  
			mat4.translate(mvMatrix,[-0.0, 0.0, -3.0]);  

			
			/*var cameraPosition = vec3.create()
			var cameraOrientation = quat4.create()
			var cameraTransform = mat4.create()
			var viewMatrix = mat4.create()
			var projectionMatrix = mat4.create()
			var viewProjectionMatrix = mat4.create()
			
			mat4.fromRotationTranslation(cameraOrientation, cameraPosition, cameraTransform)
			mat4.inverse(cameraTransform, viewMatrix)
			mat4.perspective(50, canvas.width / canvas.height, 0.1, 1000.0, projectionMatrix)
			mat4.multiply(projectionMatrix, viewMatrix, viewProjectionMatrix)
			
			var modelMatrix = mat4.create()
			mat4.identity(modelMatrix)
			
			shaderProgram.setMat4Uniform("modelMatrix", modelMatrix)
			shaderProgram.setMat4Uniform("modelViewProjectionMatrix", viewProjectionMatrix)*/

		  
		  
			gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer);  
			gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);  
			//gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesColorBuffer);  
			//gl.vertexAttribPointer(vertexColorAttribute, 4, gl.FLOAT, false, 0, 0);  
			setMatrixUniforms();  
			gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);  
		}  

		function setMatrixUniforms() 
		{
			shaderProgram.setMat4Uniform("uPMatrix", new Float32Array(perspectiveMatrix));
			shaderProgram.setMat4Uniform("uMVMatrix", new Float32Array(mvMatrix));
		}
	
	</script>

</head>	
<body>
	<canvas id="C">	</canvas>
	<script type="text/javascript">init()</script>
</body>